﻿using System.Collections.Generic;
using System.Text.RegularExpressions;
using Jayden.Dll.Sc2.Descriptions;
using Jayden.Dll.Web.HtmlControls;
using Jayden.Dll.Web.Json;
using Jayden.Sc2;

namespace Jayden.Dll.Web.Controls.Sc2
{
	public class Starcraft2Div : Div
	{
		private SearchForm m_SearchForm;
		private EntityDescriptionTable m_Entities;
		private H2 m_RaceTitle;
		private H3 m_EntityTitle;
		private H4 m_EntityType;
		private Img m_EntityIcon;
		private P m_Description;

		private H5 m_CostsTitle;
		private Ul m_EntityCost;
		private Li m_Mineral;
		private Li m_Vespene;
		private Li m_Time;
		private Li m_Supply;

		private H5 m_ActionsTitle;
		private Ul m_Actions;
		private H5 m_ProducersTitle;
		private Ul m_Producers;
		private H5 m_RequirementsTitle;
		private Ul m_Requirements;

		private Button m_Search;
		private Input m_SearchInProtoss;
		private Input m_SearchInTerran;
		private Input m_SearchInZerg;
		private Input m_SearchInUnit;
		private Input m_SearchInBuilding;
		private Input m_SearchInUpgrade;
		private Input m_SearchInOther;

		public override void Load(System.Xml.XmlNode node, HtmlControlLoader loader)
		{
			base.Load(node, loader);

			m_SearchForm = GetElementByServerId<SearchForm>("searchForm");
			m_Search = m_SearchForm.GetFormElement<Button>("search", "command");
			m_Entities = GetElementByServerId<EntityDescriptionTable>("entities", true);
			m_RaceTitle = GetElementByServerId<H2>("raceTitle");
			m_EntityTitle = GetElementByServerId<H3>("entityTitle");
			m_EntityType = GetElementByServerId<H4>("entityType");
			m_EntityIcon = GetElementByServerId<Img>("entityIcon");
			m_Description = GetElementByServerId<P>("description");

			m_CostsTitle = GetElementByServerId<H5>("costsTitle");
			m_ProducersTitle = GetElementByServerId<H5>("producersTitle");
			m_Producers = GetElementByServerId<Ul>("producers");
			m_RequirementsTitle = GetElementByServerId<H5>("requirementsTitle");
			m_Requirements = GetElementByServerId<Ul>("requirements");
			m_ActionsTitle = GetElementByServerId<H5>("actionsTitle");
			m_Actions = GetElementByServerId<Ul>("actions");

			m_EntityCost = GetElementByServerId<Ul>("entityCost");
			m_Mineral = GetElementByServerId<Li>("mineral");
			m_Vespene = GetElementByServerId<Li>("vespene");
			m_Time = GetElementByServerId<Li>("time");
			m_Supply = GetElementByServerId<Li>("supply");

			m_SearchInProtoss = m_SearchForm.GetFormElement<Input>("searchInProtoss");
			m_SearchInTerran = m_SearchForm.GetFormElement<Input>("searchInTerran");
			m_SearchInZerg = m_SearchForm.GetFormElement<Input>("searchInZerg");
			m_SearchInUnit = m_SearchForm.GetFormElement<Input>("searchInUnit");
			m_SearchInBuilding = m_SearchForm.GetFormElement<Input>("searchInBuilding");
			m_SearchInUpgrade = m_SearchForm.GetFormElement<Input>("searchInUpgrade");
			m_SearchInOther = m_SearchForm.GetFormElement<Input>("searchInOther");

			m_CostsTitle.ServerRender = false;
			m_RaceTitle.ServerRender = false;
			m_EntityTitle.ServerRender = false;
			m_EntityType.ServerRender = false;
			m_EntityIcon.ServerRender = false;
			m_EntityCost.ServerRender = false;
			m_Producers.ServerRender = false;
			m_ProducersTitle.ServerRender = false;
			m_Requirements.ServerRender = false;
			m_RequirementsTitle.ServerRender = false;
			m_Actions.ServerRender = false;
			m_ActionsTitle.ServerRender = false;
		}

		public override void ProcessHtmlRequest(HttpHandlerContext context)
		{

			SearchForm.SearchCommandHandler searchHandler = context.HandlerManager.GetHandler<SearchForm.SearchCommandHandler>();
			searchHandler.Search += new SearchForm.OnSearch(Search);

			string raceString = context.Request["race"] ?? context.Uri["race"];
			string entityString = context.Request["entity"] ?? context.Uri["entity"];

			List<EntityDescription> entities = new List<EntityDescription>();
			RaceDictionary races = new RaceDictionary();

			RaceDescription race = null;
			EntityDescription entity = null;

			if (raceString != null)
			{
				race = races[raceString];
				if (race != null && entityString != null)
					entity = race.GetEntity(entityString);
			}

			if (race != null && entity != null)
			{
				Classes.Add(race.Id.ToLowerInvariant());

				m_SearchForm.ServerRender = false;
				m_Entities.ServerRender = false;
				m_RaceTitle.ServerRender = true;
				m_RaceTitle.InnerText = race.Name;
				m_EntityTitle.ServerRender = true;
				m_EntityTitle.InnerText = entity.Name;
				m_EntityType.ServerRender = true;
				m_EntityType.InnerText = entity.Type.ToString();
				m_EntityIcon.ServerRender = true;
				m_EntityIcon.Src = "/Images/Icons/Sc2/" + entity.IconId + ".gif";
				m_EntityIcon.Alt = m_EntityIcon.Title = entity.Name;

				m_Mineral.InnerText = entity.Mineral.ToString();
				m_Vespene.InnerText = entity.Vespene.ToString();
				m_Time.InnerText = entity.Time.ToString();
				m_Supply.InnerText = entity.Supply.ToString();

				foreach (EntityDescription producer in entity.Producers)
				{
					Li li = m_Producers.AddLi();
					A a = li.AddA(null, producer.Id + ".html");
					Img img = a.AddImg(producer.Name, "/Images/Icons/Sc2/" + producer.IconId + ".gif");
					img.Title = producer.Name;
				}
				foreach (EntityDescription requirement in entity.Requirements)
				{
					Li li = m_Requirements.AddLi();
					A a = li.AddA(null, requirement.Id + ".html");
					Img img = a.AddImg(requirement.Name, "/Images/Icons/Sc2/" + requirement.IconId + ".gif");
					img.Title = requirement.Name;
				}
				foreach (ActionDescription action in entity.Actions)
				{
					Li li = m_Actions.AddLi();
					if (action is BuildActionDescription)
					{
						BuildActionDescription buildAction = action as BuildActionDescription;
						A a = li.AddA(null, buildAction.Build.Id + ".html");
						Img img = a.AddImg(buildAction.Build.Name, "/Images/Icons/Sc2/" + buildAction.Build.IconId + ".gif");
						img.Title = buildAction.Name;
					}
					else
					{
						Img img = li.AddImg(action.Name, "/Images/Icons/Sc2/" + action.IconId + ".gif");
						img.Title = action.Name;
					}
				}

				m_EntityCost.ServerRender = true;

				m_Mineral.ServerRender = (entity.Mineral != 0);
				m_Vespene.ServerRender = (entity.Vespene != 0);
				m_Time.ServerRender = (entity.Time != 0);
				m_Supply.ServerRender = (entity.Supply != 0);

				m_CostsTitle.ServerRender = m_EntityCost.ServerRender = m_Mineral.ServerRender || m_Vespene.ServerRender || m_Time.ServerRender || m_Supply.ServerRender;

				m_ProducersTitle.ServerRender = m_Producers.ServerRender = m_Producers.ChildControls.Count > 0;
				m_RequirementsTitle.ServerRender = m_Requirements.ServerRender = m_Requirements.ChildControls.Count > 0;
				m_ActionsTitle.ServerRender = m_Actions.ServerRender = m_Actions.ChildControls.Count > 0;

				m_Description.Clear();
			}
			else
			{

				foreach (RaceDescription r in races.Races)
					entities.AddRange(r.Entities);
				//entities.Sort(delegate(EntityDescription d1, EntityDescription d2) { return d1.MinTime.CompareTo(d2.MinTime); });
				m_Entities.AddCaption("Database for version " + races.Version);
				m_Entities.AddHeaders();
				foreach (EntityDescription e in entities)
					m_Entities.AddTr(e);

			}
			base.ProcessHtmlRequest(context);
		}

		public override void ProcessJsonRequest(HttpHandlerContext context)
		{
			SearchForm.SearchCommandHandler searchHandler = context.HandlerManager.GetHandler<SearchForm.SearchCommandHandler>();
			searchHandler.Search += new SearchForm.OnSearch(Search);
			base.ProcessJsonRequest(context);
		}

		void Search(HttpHandlerContext context, SearchForm.SearchValues search)
		{
			string text = search.Term;
			Regex regex = null;
			try { regex = new Regex(text, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.Compiled); }
			catch { regex = null; }

			bool searchInProtoss = (context.Request[m_SearchInProtoss.Name] == "on");
			bool searchInTerran = (context.Request[m_SearchInTerran.Name] == "on");
			bool searchInZerg = (context.Request[m_SearchInZerg.Name] == "on");

			bool searchInUnit = (context.Request[m_SearchInUnit.Name] == "on");
			bool searchInBuilding = (context.Request[m_SearchInBuilding.Name] == "on");
			bool searchInUpgrade = (context.Request[m_SearchInUpgrade.Name] == "on");
			bool searchInOther = (context.Request[m_SearchInOther.Name] == "on");

			List<EntityDescription> entities = new List<EntityDescription>();
			RaceDictionary races = new RaceDictionary();

			foreach (RaceDescription r in races.Races)
			{
				if (r.Id == "Protoss" && !searchInProtoss)
					continue;
				if (r.Id == "Terran" && !searchInTerran)
					continue;
				if (r.Id == "Zerg" && !searchInZerg)
					continue;
				entities.AddRange(r.Entities);
			}
			//entities.Sort(delegate(EntityDescription d1, EntityDescription d2) { return d1.MinTime.CompareTo(d2.MinTime); });
			m_Entities.AddCaption("Database for version " + races.Version);
			m_Entities.AddHeaders();
			foreach (EntityDescription e in entities)
			{
				switch (e.Type)
				{
					case Jayden.Dll.Sc2.Enums.EntityType.Other:
						if (!searchInOther)
							continue;
						break;
					case Jayden.Dll.Sc2.Enums.EntityType.Building:
						if (!searchInBuilding)
							continue;
						break;
					case Jayden.Dll.Sc2.Enums.EntityType.Unit:
						if (!searchInUnit)
							continue;
						break;
					case Jayden.Dll.Sc2.Enums.EntityType.Upgrade:
						if (!searchInUpgrade)
							continue;
						break;
				}
				if (regex != null && regex.IsMatch(e.Name))
				{
					Tr tr = m_Entities.AddTr(e);
					(tr.ChildControls[2] as Td).MarkText(regex, context.Translator);
				}
				else if(e.Name.Contains(text))
					m_Entities.AddTr(e);
			}

			if (context.Json != null)
			{
				JsonObject table = new JsonObject();
				table.Add("html", m_Entities.ToInnerHtml(context.Translator));
				context.Json.Add(m_Entities.Id, table);
			}

		}

		public override void ProcessJsRequest(HttpHandlerContext context)
		{
			base.ProcessJsRequest(context);
			string id = m_Entities.Id;
			context.Js[id].AppendAjaxHtmlHandler(m_Entities, true, false);
			context.Js[id].AppendOnInit(@"
	var $form = $('#" + m_SearchForm.Id + @"');
	var $search = $('#" + m_Search.Id + @"');
	var submit = function () {
		return JAYDEN.sfn.submitAjax($form, $search);
	};
	$('#" + m_SearchInBuilding.Id + @"').click(submit);
	$('#" + m_SearchInUnit.Id + @"').click(submit);
	$('#" + m_SearchInOther.Id + @"').click(submit);
	$('#" + m_SearchInUpgrade.Id + @"').click(submit);
	$('#" + m_SearchInProtoss.Id + @"').click(submit);
	$('#" + m_SearchInTerran.Id + @"').click(submit);
	$('#" + m_SearchInZerg.Id + @"').click(submit);
");
		}
	}
}
